package org.komarichin.jpa.dao;

import org.komarichin.jpa.entity.IRole;
import org.komarichin.jpa.entity.IUser;
import org.komarichin.jpa.entity.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.orm.jpa.support.JpaDaoSupport;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * User: Michael Komarichin
 * Date: 28.09.2009
 * Time: 13:36:52
 */

@Transactional(readOnly = true)
public class UserDAO extends JpaDaoSupport implements IUserDAO {
    private static final Logger log = LoggerFactory.getLogger(UserDAO.class);

    /**
     * {@inheritDoc}
     */
    @Override
    @Transactional(readOnly = false)
    public IUser enroll(String login, String password, String hint, IRole role) {
        log.debug("enroll#login: {}, password: {}, hint: {}", new Object[]{login, password, hint});
        IUser user = new User();
        user.setHint(hint);
        user.setLogin(login);
        user.setPassword(password);
        user.setRegistration(new Date());
        user.setLastLogin(new Date());
        getJpaTemplate().persist(user);
        user.setRole(role.getId());
        getJpaTemplate().merge(user);

        log.debug("persists user object: {}", user);
        return user;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @SuppressWarnings("unchecked")
    public IUser login(String login, String password) {
        log.debug("login#login: {}, password: {}", login, password);
        Map<String, String> params = new HashMap<String, String>();
        params.put("login", login);
        params.put("password", password);
        List<IUser> users = getJpaTemplate().findByNamedQueryAndNamedParams("user.login", params);
        log.debug("result: {}", users);
        return users != null && users.size() > 0 ? users.get(0) : null;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @SuppressWarnings("unchecked")
    public IUser forgot(String login, String hint) {
        log.debug("forgot#login: {}, hint: {}", login, hint);
        Map<String, String> params = new HashMap<String, String>();
        params.put("login", login);
        params.put("hint", hint);
        List<IUser> users = getJpaTemplate().findByNamedQueryAndNamedParams("user.forgotPassword", params);
        log.debug("result: {}", users);
        return users != null && users.size() > 0 ? users.get(0) : null;
    }

    @Override
    @SuppressWarnings("unchecked")
    public IUser findByName(String login) {
        log.debug("findByName#login: {}", login);
        Map<String, String> params = new HashMap<String, String>();
        params.put("login", login);
        List users = getJpaTemplate().findByNamedQueryAndNamedParams("user.findByLogin", params);
        log.debug("result: {}", users);
        return users != null && users.size() > 0 ? (IUser) users.get(0) : null;
    }

    @Override
    public boolean isUserExists(String login) {
        return findByName(login) != null;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public IUser getUserById(Long id) {
        log.debug("getUserById#id : {}", id);
        return getJpaTemplate().find(IUser.class, id);
    }


    /**
     * {@inheritDoc}
     */
    @SuppressWarnings("unchecked")
    @Override
    public List<IUser> getAll() {
        log.debug("getAll");
        return getJpaTemplate().findByNamedQuery("user.findAll");
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @SuppressWarnings("unchecked")
    public List<IUser> getAllowUsers(Long permission) {
        log.debug("getAllowUsers#permission : {}", permission);
        Map<String, Long> params = new HashMap<String, Long>();
        params.put("permission", permission);
        return getJpaTemplate().findByNamedQueryAndNamedParams("user.findAllowUsers", params);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @Transactional(readOnly = false)
    public void save(IUser object) {
        log.debug("save#object : {}", object);
        getJpaTemplate().persist(object);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @Transactional(readOnly = false)
    public void update(IUser object) {
        log.debug("update#object : {}", object);
        getJpaTemplate().merge(object);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @Transactional(readOnly = false)
    public void saveOrUpdate(IUser object) {
        log.debug("saveOrUpdate#object : {}", object);
        getJpaTemplate().merge(object);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @Transactional(readOnly = false)
    public void delete(IUser object) {
        log.debug("delete#object : {}", object);
        getJpaTemplate().merge(object);
    }

}
